package main

import (
	"errors"
	"flag"
	"fmt"
	"hash"
	"hash/fnv"
	"io"
	"os"
	"strings"
)

var vo = flag.String("v", "64a", "fnv算法的hash方法, 支持64|64a|32|32a|128|128a")

func newFnv() (hash.Hash, error) {
	switch strings.ToLower(*vo) {
	case "64":
		return fnv.New64(), nil
	case "64a":
		return fnv.New64a(), nil
	case "32":
		return fnv.New32(), nil
	case "32a":
		return fnv.New32a(), nil
	case "128":
		return fnv.New128(), nil
	case "128a":
		return fnv.New128a(), nil
	}
	return nil, errors.New("not supported")
}

func getStr() (b []byte, err error) {
	if len(os.Args) > 1 {
		b = []byte(os.Args[1])
		return
	}
	b, err = io.ReadAll(os.Stdin)
	return
}

func fnvSum() (uint64, error) {
	h, err := newFnv()
	if err != nil {
		return 0, err
	}
	b, err := getStr()
	if err != nil {
		return 0, err
	}
	h.Write(b)
	h32, ok := h.(hash.Hash32)
	if ok {
		return uint64(h32.Sum32()), nil
	}
	h64, ok := h.(hash.Hash64)
	if ok {
		return h64.Sum64(), nil
	}
	return 0, errors.New("fnvsum error")
}

func main() {
	flag.Parse()
	n, err := fnvSum()
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	fmt.Println(n)
}
